package destinychild;

import aoshiScript.entity.IWuNa;
import aoshiScript.entity.WuNa;
import com.alibaba.fastjson.JSONObject;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import commons.entity.Constant;
import commons.entity.NativeCp;
import commons.util.GameUtil;
import commons.util.PropertiesUtil;
import commons.util.ThreadUtil;
import destinychild.entity.RaidFilterMenu;
import destinychild.entity.RaidStartPage;
import fgoScript.entity.PointColor;
import fgoScript.exception.AppNeedRestartException;
import fgoScript.exception.AppNeedStopException;
import fgoScript.exception.AppNeedUpdateException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * @description: Raid战斗挂机
 * @author: RENZHEHAO
 * @create: 2019-06-03 21:14
 **/
public class Raid implements IRaid, IModule{
    private static final Logger LOGGER = LogManager.getLogger(Raid.class);
    private ThreadPoolTaskExecutor frontExcutor;
    private ThreadPoolTaskExecutor guardExcutor;
    private WuNa wuna;
    private RaidFilterMenu menu;
    private RaidStartPage rsPage;
    private boolean StopNoTiket;

    public void setFrontExcutor(ThreadPoolTaskExecutor frontExcutor) {
        this.frontExcutor = frontExcutor;
    }

    public void setGuardExcutor(ThreadPoolTaskExecutor guardExcutor) {
        this.guardExcutor = guardExcutor;
    }

    @Override
    public void start() throws AppNeedRestartException {
        setStopNoTiket(true);
        toggle();
    }

    @Override
    public void stop() throws AppNeedRestartException {
        toggle();
    }

    @Override
    public void toggle() throws AppNeedRestartException {
        if (!isGo()){
            LOGGER.info("启动raid脚本");
            setGo(true);
            //初始化全关参数
            wuna.setAllStop(false);
            try {
                raidBattleStart();
            } catch (AppNeedRestartException e) {
                stopMethod();
                throw e;
            }
            setGo(false);
        }else{
            stopMethod();
        }

    }
    private void stopMethod(){
        LOGGER.info("关闭raid脚本");
        //关闭主线程
        setGo(false);
        //关闭吴娜 关闭分线程
        wuna.setAllStop(true);
        //关闭咕哒子等待
        GameUtil.setSTOP_SCRIPT(true);
        //等待2个线程池空闲
        try {
            ThreadUtil.waitUntilNoneThread(frontExcutor);
            ThreadUtil.waitUntilNoneThread(guardExcutor);
        } catch (AppNeedRestartException e) {
            LOGGER.error(e.getMessage(),e);
        }
    }
    public RaidFilterMenu getMenu() {
        if (menu == null) {
            String filepath = NativeCp.getUserDir() + "/config/"+ Constant.DC+"/RaidFilterMenu_"+NativeCp.getUserName()+".json";
            menu = JSONObject.parseObject(GameUtil.getJsonString(filepath), RaidFilterMenu.class);
        }
        return menu;
    }

    public RaidStartPage getRsPage() {
        if (rsPage == null) {
            String filepath = NativeCp.getUserDir() + "/config/"+ Constant.DC+"/RaidStartPage.json";
            rsPage = JSONObject.parseObject(GameUtil.getJsonString(filepath), RaidStartPage.class);
        }
        return rsPage;
    }

    public void setWuna(WuNa wuna) {
        this.wuna = wuna;
    }

    private boolean go = false;

    public boolean isGo() {
        return go;
    }

    public void setGo(boolean go) {
        this.go = go;
    }
    private void guardCheck(){
        //单启动一个线程:实时点色教程操作。用来处理断线，重启，升级，补票等操作(脚本文件)
        guardExcutor.execute(()-> {
            LOGGER.info("《《《异常处理点击线程启动》》》");
            try {
                wuna.alwaysClickForStrategy("optionClick", 2000, true, false, false,false,0,Constant.DC + "/", null);
            } catch (AppNeedRestartException e) {
                LOGGER.error(e.getMessage(),e);
            } catch (AppNeedStopException e) {
                e.printStackTrace();
            }
            LOGGER.info("《《《异常处理点击线程结束》》》");
        });
        //单启动一个线程:检测并处理战斗条件（逻辑判断）
        guardExcutor.execute(()-> {
            getRsPage();
            int soutCount = 0;
            while(!wuna.isAllStop()){
                //喊话
                if(++soutCount%10 == 0){
                    soutCount = 0;
                    LOGGER.info("《《《条件检测战斗，执行中》》》》" + System.currentTimeMillis());
                }
                //如果是战斗页面
                if(GameUtil.likeEqualColor(rsPage.getStartColor(),GameUtil.getScreenPixel(rsPage.getStartPoint()),5)){
                    // 如果 用户名是RZH_SERVER，平且没有票，并且是开始战斗点
                    if ("RZH_SERVER".equals(NativeCp.getUserName())
                            && GameUtil.likeEqualColor(rsPage.getNoTicketColor(),GameUtil.getScreenPixel(rsPage.getNoTicketPoint()),5)
                            && !GameUtil.likeEqualColor(rsPage.getTenTicketColor(),GameUtil.getScreenPixel(rsPage.getTenTicketPoint()),5)
                    ){
                        try {
                            noTicketIsUserIsStartDo();
                        } catch (AppNeedStopException e) {
                            e.printStackTrace();
                        }
                    }else{
                        try {
                            hasTickeDo();
                        } catch (AppNeedStopException e) {
                            e.printStackTrace();
                        }
                    }
                }
                // 检测间隔
                GameUtil.delay(3000);

            }
        });
    }
    private void hasTickeDo() throws AppNeedStopException {
        //等待3秒，休息一下
        LOGGER.info("《《战斗按钮-等待3秒》》");
        GameUtil.delay(3000);
        //不是等级40
        boolean noLevel40 = !GameUtil.likeEqualColor(GameUtil.getScreenPixel(rsPage.getLevelPoint()),rsPage.getLevelColor());
        //没有票 再检测下比较稳
        boolean noTicket = GameUtil.likeEqualColor(GameUtil.getScreenPixel(rsPage.getNoTicketPoint()),rsPage.getNoTicketColor())
                && !GameUtil.likeEqualColor(GameUtil.getScreenPixel(rsPage.getTenTicketPoint()),rsPage.getTenTicketColor());
        //没有排行，即没人打
        boolean noRank = !GameUtil.likeEqualColor(GameUtil.getScreenPixel(rsPage.getRankPoint()),rsPage.getRankColor());
        if(noLevel40 || noTicket || noRank){

            GameUtil.getMymouse().mouseMoveByPoint(rsPage.getReturnPoint(),true,true);

            GameUtil.getMymouse().mousePressAndRelease(50);

            LOGGER.info("《《条件不足-返回页面》》");
        }else {
            // 这里特指停止runclick
            wuna.setGO(false);
            if(GameUtil.likeEqualColor(GameUtil.getScreenPixel(rsPage.getDoubleTicketPoint()),rsPage.getDoubleTicketColor())){
                LOGGER.info("《《选择双倍票》》");

                GameUtil.getMymouse().mouseMoveByPoint(rsPage.getDoubleTicketPoint(),true,true);

                GameUtil.getMymouse().mousePressAndRelease(50);

                GameUtil.delay(1000);
            }
            LOGGER.info("《《点击开始战斗》》");

            GameUtil.getMymouse().mouseMoveByPoint(rsPage.getStartPoint(),true,true);

            GameUtil.getMymouse().mousePressAndRelease(50);

            // 等待10秒，执行结束检测
            LOGGER.info("《《等待10秒-休息一下》》");
            GameUtil.delay(10000);
        }

    }
    private void noTicketIsUserIsStartDo() throws AppNeedStopException {
        //如果 选择 无票结束raid，则结束raid模块
        if(isStopNoTiket()){
            setStopNoTiket(false);
            LOGGER.info("《《无票-返回页面-关闭raid脚本》》");

            GameUtil.getMymouse().mouseMoveByPoint(rsPage.getReturnPoint(),true,true);

            GameUtil.getMymouse().mousePressAndRelease(50);

            //关闭吴娜
            wuna.setAllStop(true);
            //关闭咕哒子等待
            GameUtil.setSTOP_SCRIPT(true);
            //等待2个线程池空闲
            try {
                ThreadUtil.waitUntilNoneThread(frontExcutor);
                ThreadUtil.waitUntiloneThread(guardExcutor);
            } catch (AppNeedRestartException e) {
                LOGGER.error(e.getMessage(),e);
            }
            setGo(false);
        }else{
            LOGGER.info("《《无票，等待30分钟》》");
            GameUtil.delay(60*1000*30);

            GameUtil.getMymouse().mouseMoveByPoint(rsPage.getReturnPoint(),true,true);
            GameUtil.getMymouse().mousePressAndRelease(50);

            LOGGER.info("《《等待完-返回页面》》");
        }
    }
    private int getFactor(){
        String multiFactor = PropertiesUtil.getValueFromFileNameAndKey("multiFactor" , "changeButton_" + NativeCp.getUserName(), "");
        int factor = Integer.parseInt(multiFactor.trim());
        return factor;
    }
    @Override
    public void raidBattleStart() throws AppNeedRestartException {
        //启动后台线程guardTPool
        guardCheck();
        while (isGo()) {
            try {
                // 设置列表过滤项为：未参加，参加人数（降序）
                    setFilterOptions();
                // 等待线程池空闲
                ThreadUtil.waitUntilNoneThread(frontExcutor);
                // 执行点击脚本。
                    runClick();
                // 等待线程池空闲
                ThreadUtil.waitUntilNoneThread(frontExcutor);
                // 当完成一场战斗后，点结束按钮。结束所有线程
                    stopOneBattle();
                // 等待线程池空闲
                ThreadUtil.waitUntilNoneThread(frontExcutor);
            } catch (AppNeedUpdateException e) {
                LOGGER.error(e.getMessage(),e);
            } catch (AppNeedStopException e) {
                LOGGER.info(e.getMessage(),e);
                break;
            }
        }
    }
    /**
     * @Description: 递归判断线程池中是否只有一个线程，然后在执行点击脚本
     * @return: void
     * @Author: RENZHEHAO
     * @Date: 2019/6/5
     */
    private void runClick(){
        // 启动另一个线程：实时点色操作方法。
        frontExcutor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    wuna.setMinValues(17);
                    wuna.alwaysClickForStrategy("runClick", null, false,true, false,false,0,Constant.DC + "/", null);
                } catch (AppNeedRestartException e) {
                    LOGGER.error(e.getMessage(),e);
                } catch (AppNeedStopException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    @Override
    public void raidBattleStop() {
    }

    private void setFilterOptions() throws AppNeedUpdateException, AppNeedRestartException, AppNeedStopException {
        // 最大循环次数
        int maxCicle = 60;
        getMenu();
        //等待菜单按钮
        LOGGER.info("等待菜单按钮");
        List<PointColor> pocoList = new ArrayList<PointColor>();
        pocoList.add(new PointColor(menu.getMenuPoint(), menu.getMenuColor(), true));
        GameUtil.waitUntilAllColor(pocoList,500, Constant.DCMonitor);
        //如果未出现“确认按钮”，点击“菜单按钮”，
        Color tempColor;
        for (int i = 0; i < maxCicle && isGo(); i++) {
            tempColor = GameUtil.getScreenPixel(menu.getConfirmPoint());
            if (!GameUtil.likeEqualColor(tempColor,menu.getConfirmColor(),2)) {
                LOGGER.info("未出现确认按钮点击！");

                GameUtil.getMymouse().mouseMoveByPoint(menu.getMenuPoint(),true,true);

                GameUtil.getMymouse().mousePressAndRelease(50);

                GameUtil.delay(2000);
            }else{
                break;
            }
        }
        //单开一个线程用于选择过滤项
        frontExcutor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    wuna.alwaysClickForStrategy("filterClick", null, false, true, false,false,0,Constant.DC + "/", null);
                } catch (AppNeedRestartException e) {
                    LOGGER.error(e.getMessage(),e);
                } catch (AppNeedStopException e) {
                    e.printStackTrace();
                }
            }
        });
        //如果两个颜色符合条件，点击确认。
        int count;
        Color temp;
        for (int i = 0; i < maxCicle && isGo(); i++) {
            if(wuna.isAllStop()){
                break;
            }
            count = 0;
            temp = GameUtil.getScreenPixel(menu.getUnDoPoint());
            if (GameUtil.likeEqualColor(temp, menu.getUnDoColor(), 5)) {
                count++;
            }
            temp = GameUtil.getScreenPixel(menu.getPartPoint());
            if (GameUtil.likeEqualColor(temp, menu.getPartColor(), 5)) {
                count++;
            }
            LOGGER.info("过滤符合个数： " + count +" 个");
            GameUtil.delay(1000);
            if (count == 2) {
                wuna.setGO(false);
                //点击确定按钮
                for (int j = 0; j < maxCicle; j++) {
                    if(wuna.isAllStop()){
                        break;
                    }
                    temp = GameUtil.getScreenPixel(menu.getConfirmPoint());
                    if (GameUtil.likeEqualColor(temp,menu.getConfirmColor())){

                        GameUtil.getMymouse().mouseMoveByPoint(menu.getConfirmPoint(),true,true);

                        GameUtil.getMymouse().mousePressAndRelease(50);

                    }else if (GameUtil.likeEqualColor(GameUtil.getScreenPixel(menu.getLoadPoint()),menu.getLoadColor())){
                    } else {
                        maxCicle = 0;
                    }
                    GameUtil.delay(1000);
                }
            }
        }
    }
    private void stopOneBattle() throws AppNeedStopException {
        Color tempColor;
        int size = menu.getStopPointList().size();
        boolean clickFlag = true;
        boolean continuFLag=true;
        for (int count = 0; count < 100 && continuFLag && isGo(); count++) {
            if (count % 10 == 0 && GameUtil.likeEqualColor(menu.getMenuColor(),GameUtil.getScreenPixel(menu.getMenuPoint()),2)) {
                LOGGER.info("战斗被提前结束，不明原因，发现菜单按钮，重新开始脚本");
                continuFLag = false;
            }
            tempColor = GameUtil.getScreenPixel(menu.getsRconfirmPoint());
            if (GameUtil.likeEqualColor(tempColor,menu.getsRconfirmColor(),2)) {
                LOGGER.info("退出SR菜单，返回主界面。");

                GameUtil.getMymouse().mouseMoveByPoint(menu.getsRclosePoint(),true,true);

                GameUtil.getMymouse().mousePressAndRelease(50);

            }
            LOGGER.info("检测战斗结束标志_" + count);
            for (int i = 0; i < size && continuFLag; i++) {
                tempColor = GameUtil.getScreenPixel(menu.getStopPointList().get(i));
                if (GameUtil.likeEqualColor(tempColor,menu.getStopColorList().get(i),2)) {
                    //防止色彩变化影响，等待5秒
                    GameUtil.delay(5000);
                    LOGGER.info("战斗结束，点击返回");
                    // 循环点击，防止点击无效。
                    do {
                        tempColor = GameUtil.getScreenPixel(menu.getStopPointList().get(i));
                        if (!GameUtil.likeEqualColor(tempColor,menu.getStopColorList().get(i),2)) {
                            clickFlag=false;
                        }else{

                            GameUtil.getMymouse().mouseMoveByPoint(menu.getStopClickPoint(),true,true);

                            GameUtil.getMymouse().mousePressAndRelease(50);

                        }
                        GameUtil.delay(2000);
                    }while (clickFlag);
                    continuFLag = false;
                }
            }
            GameUtil.delay(4000);
        }
        //防止过滤超时后，仍然执行runclick脚本
        wuna.setGO(false);
    }

    public boolean isStopNoTiket() {
        return StopNoTiket;
    }

    public void setStopNoTiket(boolean stopNoTiket) {
        this.StopNoTiket = stopNoTiket;
    }

    public static void main(String[] args) {
    }

}
